package com.sopaths.crawler.$51job;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.inject.Named;

import org.apache.http.impl.client.HttpClients;
import org.apache.log4j.Logger;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.sopaths.contract.domain.Company;
import com.sopaths.contract.domain.CompanyType;
import com.sopaths.contract.domain.EducationBackground;
import com.sopaths.contract.domain.Range;
import com.sopaths.contract.domain.Recruitment;
import com.sopaths.crawler.RecruitmentCrawler;
import com.sopaths.crawler.tasks.RecruitmentCrawlerTask;
import com.sopaths.crawler.util.ElementsHelper;

@Named("51JobRecruitmentCrawler")
public class $51JobRecruitmentCrawler extends RecruitmentCrawler {

	private final Logger logger = Logger.getLogger($51JobRecruitmentCrawler.class);

	@Resource(name="companySizeDictionary4$51Job")
	private Map<String, Range> companySizeDictionary;

	@Resource(name="companyTypeDictionary4$51Job")
	private Map<String, CompanyType> companyTypeDictionary;

	@Resource(name="experienceDictionary4$51Job")
	private Map<String, Range> experienceDictionary;

//	@Resource(name="jobStatusDictionary4$51Job")
//	private Map<String, JobStatus> jobStatusDictionary;

	@Resource(name="educationBackgroundDictionary4$51Job")
	private Map<String, EducationBackground> educationBackgroundDictionary;

	@Resource(name="salaryDictionary4$51Job")
	private Map<String, Range> salaryDictionary;

//	@Resource(name="administrationExperienceDictionary4$51Job")
//	private Map<String, Boolean> administrationExperienceDictionary;

	public $51JobRecruitmentCrawler() {
		this.setResponseEncoding("gb2312");
	}

	@Override
	protected String assembleRecruitmentUrl(RecruitmentCrawlerTask task) {
		return task.getUrl();
	}

	@Override
	protected void assembleRecruitmentTaskResult(RecruitmentCrawlerTask task, Document document) {
		try {
			Elements elements = document.select(".s_txt_jobs");
			for (Element element : elements) {
				Recruitment recruitment = new Recruitment();
				recruitment.setUrl(task.getUrl());

				Company company = new Company();
				Elements companyNameElements = element.select(">table:nth-of-type(1) tbody tr:nth-child(2) table tbody tr td a");
				company.setName(ElementsHelper.textUniqueElement(companyNameElements));

				String companyInfoHtml = ElementsHelper.htmlUniqueElement(element.select(">table:nth-of-type(1) tbody tr:nth-child(3) td"));
				if (companyInfoHtml != null) {
					String[] companyInfoItems = companyInfoHtml.split("<br /><br />");
					Pattern companyInfoRegex = Pattern.compile("<strong>(.*)</strong>&nbsp;&nbsp;(.*)");
					for (String companyInfoItem : companyInfoItems) {
						Matcher matcher = companyInfoRegex.matcher(companyInfoItem);
						if (matcher.matches()) {
							String infoName = matcher.group(1);
							String infoValue = matcher.group(2);
							switch (infoName) {
								case "公司行业：":
									company.setIndustry(infoValue);
									break;
								case "公司性质：":
									company.setType(companyTypeDictionary.get(infoValue));
									break;
								case "公司规模：":
									company.setSize(companySizeDictionary.get(infoValue));
									break;
								default:
									logger.error("Unknown company info name. Name: " + infoName);
							}
						}
					}
				}
				company.setProfile(ElementsHelper.textUniqueElement(element.select(">div:nth-of-type(3)>div:nth-child(2)")));
				recruitment.setCompany(company);

				recruitment.setJobTitle(ElementsHelper.textUniqueElement(element.select("table:nth-of-type(1) tbody tr:nth-child(1) td")));

				//String issueDate = ElementsHelper.textUniqueElement(element.select(">div:nth-of-type(1) .grayline table tr:nth-child(1)>td:nth-child(2)"));

				recruitment.setExperience(experienceDictionary.get(ElementsHelper.textUniqueElement(element.select(">div:nth-of-type(1) .grayline table td:containsOwn(工作年限：)+td"))));
				recruitment.setEducationBackground(educationBackgroundDictionary.get(ElementsHelper.textUniqueElement(element.select(">div:nth-of-type(1) .grayline table td:matchesOwn(学.*历：)+td"))));
				recruitment.setSalary(salaryDictionary.get(ElementsHelper.textUniqueElement(element.select(">div:nth-of-type(1) .grayline table td:contains(薪水范围：)+td"))));
				recruitment.setRecruitingNumber(ElementsHelper.textUniqueElement(element.select(">div:nth-of-type(1) .grayline table td:contains(招聘人数：)+td")));
				recruitment.setPrimaryLocation(ElementsHelper.textUniqueElement(element.select(">div:nth-of-type(1) .grayline table td:contains(工作地点：)+td")));
				recruitment.setJobType(ElementsHelper.ownTextUniqueElement(element.select(">div:nth-of-type(1) .grayline table td:contains(职位职能:)")));
				recruitment.setJobDescription(ElementsHelper.textUniqueElement(element.select(">div:nth-of-type(1) .grayline table td strong:contains(职位描述:)~div")));

//				recruitment.setAdministrationExperience(administrationExperienceDictionary.get(ElementsHelper.textUniqueElement(element.select(".terminalpage-table:nth-child(2) tbody tr:nth-child(2) td:nth-child(4)"))));
//				recruitment.setJobStatus(jobStatusDictionary.get(ElementsHelper.textUniqueElement(element.select(".terminalpage-table:nth-child(2) tbody tr:nth-child(1) td:nth-child(4)"))));
//				recruitment.setContactInformation(ElementsHelper.textUniqueElement(element.select("div:nth-child(3)>div h2")));
				task.setResult(recruitment);
			}
		} catch (Exception ex) {
			logger.error("An error occurred while assemble recruitment. URL: " + task.getUrl(), ex);
		}
	}

	public void setCompanySizeDictionary(Map<String, Range> companySizeDictionary) {
		this.companySizeDictionary = companySizeDictionary;
	}

	public void setCompanyTypeDictionary(
			Map<String, CompanyType> companyTypeDictionary) {
		this.companyTypeDictionary = companyTypeDictionary;
	}

	public void setExperienceDictionary(Map<String, Range> experienceDictionary) {
		this.experienceDictionary = experienceDictionary;
	}

//	public void setJobStatusDictionary(Map<String, JobStatus> jobStatusDictionary) {
//		this.jobStatusDictionary = jobStatusDictionary;
//	}

	public void setEducationBackgroundDictionary(
			Map<String, EducationBackground> educationBackgroundDictionary) {
		this.educationBackgroundDictionary = educationBackgroundDictionary;
	}

	public void setSalaryDictionary(Map<String, Range> salaryDictionary) {
		this.salaryDictionary = salaryDictionary;
	}

//	public void setAdministrationExperienceDictionary(
//			Map<String, Boolean> administrationExperienceDictionary) {
//		this.administrationExperienceDictionary = administrationExperienceDictionary;
//	}

	public static void main(String[] args) {
		RecruitmentCrawlerTask task = new RecruitmentCrawlerTask();
		task.setUrl("http://search.51job.com/job/58356799,c.html");
		$51JobRecruitmentCrawler crawler = new $51JobRecruitmentCrawler();
		crawler.setHttpClient(HttpClients.createDefault());
		crawler.crawl(task);
	}
}
